!function(window, fn) {
	if ('function' === typeof define && define.amd) {
		define(['utils', 'baseCanvas'], function(_$, A) {
			return fn(_$, A);
		});
	} else {
		window.PaintCanvas = fn(utils, BaseCanvas);
	}
}(window, function(_$, BaseCanvas) {
	var PaintCanvas = function(canvas, ops) {
		if (canvas && canvas.getContext) {
			BaseCanvas.call(this, canvas, ops);
			// 状态函数缓存
			this.statescall = {
				// 初始化状态回调
				init: [function() {
					// 清空加载完成回调缓存
					this.statescall.loaded = [];
					this.state = this.states.INIT;
					this.ctx.clearRect(0, 0, this.width, this.height);
					this.ctx.lineWidth = this.lineWidth;
					this.setColorStyle(this.shapeColor);
					this.mousedown = false;
					this.mousemove = false;
					// 图片缓存
					this.imgCache = [];
					// 起始点
					this.startPoint = {};
				}],
				// 图片加载完状态回调
				loaded: []
			};
			this.options = _$.extend({}, this.defaultOptions, ops || {});
			// 绘制样式
			this.lineWidth = this.options.lineWidth[0];
			this.shapeColor = this.options.lineColors[0];
			// 默认绘制类型
			this.shapeType = 'RECT';
			// 绑定事件
			this.bindEvent();
			// 初始化
			this.init();
			if (this.options.control) {
				this.initControl();
			}
		}
	};
	_$.extendProto(PaintCanvas, BaseCanvas);
	_$.extend(PaintCanvas.prototype, {
		// 默认属性
		defaultOptions: {
			// 控制面板
			control: null,
			// 画笔颜色
			lineColors: ['#0018ba', '#ffc200', '#f32f15', '#cccccc', '#5ab639', '#000'],
			// 画笔粗细
			lineWidth: [2, 3, 4]
		},
		// 设置画笔粗细
		setCanvasSize: function(size) {
			this.setCanvasWidth(size.width);
			this.setCanvasHeight(size.height);
		},
		// 设置画笔
		restoreCtx: function() {
			this.ctx.lineWidth = this.lineWidth;
			this.setColorStyle(this.shapeColor);
		},
		// 画图前置
		beforeDraw: function(maxSize) {
			this.setCanvasSize(maxSize);
		},
		// 画图后置
		afterDraw: function() {
			this.restoreCtx();
		},
		// 设置画布宽度
		setWidth: function(width) {
			this.__super__('setWidth', width);
			this.restoreCtx();
		},
		// 设置画布高度
		setHeight: function(height) {
			this.__super__('setHeight', height);
			this.restoreCtx();
		},
		// 面板
		_panels: {
			shape: '图形',
			color: '画笔颜色',
			brush: '画笔大小'
		},
		// 模板
		_temps: {
			shape: '<li class="{{selected}}" shapeType="{{shape}}"><div class="shapeType-{{shape}} shape-icon-type"></div></li>',
			color: '<li class="{{selected}}" color="{{color}}"><div style="background: {{color}};"></div></li>',
			brush: '<li class="{{selected}}" lineWidth="{{brush}}"><div style="width: {{brush}}px;"></div></li>'
		},
		// 解析模板
		_formatTemp: function(temp, obj) {
			_$.each(obj || {}, function(key, value) {
				temp = temp.replace(new RegExp('{{' + key + '}}', 'g'), value);
			});
			return temp;
		},
		// 策略解析
		_formatStrategies: {
			shape: function(obj, key, value) {
				obj.shape = key;
			}
		},
		// 创建面板
		_createPanel: function(type, source, i) {
			var c = this, panel = document.createElement('div'), contents = ['<h5>', c._panels[type], '</h5>', '<ul>'], obj = {};
			panel.className = 'canvas-' + type;
			_$.each(source || [], function(key, value) {
				obj[type] = value;
				obj.selected = (key == i ? 'selected' : '');
				c._formatStrategies[type] && c._formatStrategies[type](obj, key, value);
				contents.push(c._formatTemp(c._temps[type], obj));
			});
			contents.push('</ul>');
			panel.innerHTML = contents.join('');
			c.options.control.appendChild(panel);
		},
		// 设置颜色
		setColorStyle: function(color) {
			if (color) {
				this.ctx.strokeStyle = color;
				this.ctx.fillStyle = color;
				this.shapeColor = color;
			}
		},
		// 设置画图形状
		setShapeType: function(type) {
			if (type) {
				this.shapeType = type.key ? type.key : type;
			}
		},
		// 设置画笔大小
		setLineWidth: function(width) {
			if (!isNaN(width)) {
				this.ctx.lineWidth = width;
				this.lineWidth = width;
			}
		},
		// 初始化控制面板
		initControl: function() {
			var c = this, control = c.options.control, createPanel = function(className, title, fn) {
				var panel = document.createElement('div');
				panel.className = className;
				panel.innerHTML = ['<h5>', title, '</h5>', fn ? fn() : ''].join('');
				control.appendChild(panel);
				return panel;
			};
			c._createPanel('shape', c.shapeTypes, 'RECT');
			c._createPanel('color', c.options.lineColors, 0);
			c._createPanel('brush', c.options.lineWidth, 0);
			// 设置属性
			_$.delegate(control, 'li', 'click', function(e) {
				c.setColorStyle(this.getAttribute('color'));
				c.setShapeType(c.shapeTypes[this.getAttribute('shapetype')]);
				c.setLineWidth(parseInt(this.getAttribute('lineWidth')));
				var pre = this.previousSibling, next = this.nextSibling;
				// 取消兄弟节点的选中状态
				while (pre) {
					_$.removeClass(pre, 'selected');
					pre = pre.previousSibling;
				}
				while (next) {
					_$.removeClass(next, 'selected');
					next = next.nextSibling;
				}
				_$.addClass(this, 'selected');
				return false;
			});
		},
		// 检查位置
		_checkPoint: function(x, y) {
			return this.startPoint.x !== undefined && this.startPoint.y !== undefined && x !== undefined && y !== undefined;
		},
		// 绘制形状策略
		shapeTypes: {
			// 画矩形
			RECT: {
				key: 'RECT',
				_draw: function(x, y) {
					var ctx = this.ctx;
					ctx.beginPath();
					ctx.strokeRect(Math.min(this.startPoint.x, x), Math.min(this.startPoint.y, y), Math.abs(x - this.startPoint.x), Math.abs(y - this.startPoint.y));
					return true;
				}
			},
			// 画圆
			CIRCLE: {
				key: 'CIRCLE',
				_draw: function(x, y) {
					var ctx = this.ctx, radius = Math.sqrt(Math.pow(x - this.startPoint.x, 2) + Math.pow(y - this.startPoint.y, 2)) / 2;
					ctx.beginPath();
					ctx.arc((x + this.startPoint.x) / 2, (y + this.startPoint.y) / 2, radius, 0, Math.PI * 2, true);
					ctx.stroke();
					return true;
				}
			},
			// 画心
			HEART: {
				key: 'HEART',
				_draw: function(x, y) {
					var ctx = this.ctx, left = (x + this.startPoint.x) / 2, top = (y + this.startPoint.y) / 2,
					// 半径
					r = Math.sqrt(Math.pow(x - this.startPoint.x, 2) + Math.pow(y - this.startPoint.y, 2)) / 5, balance = 0.75;
					ctx.beginPath();
					ctx.arc(left - r, top, r, Math.PI * balance, 0, false);
					ctx.arc(left + r, top, r, Math.PI, Math.PI * (1 - balance), false);
					ctx.lineTo(left, top + Math.PI * balance * r);
					ctx.closePath();
					ctx.stroke();
					return true;
				}
			},
			// 画星
			STAR: {
				key: 'STAR',
				_draw: function(x, y) {
					var ctx = this.ctx, radius = Math.sqrt(Math.pow(x - this.startPoint.x, 2) + Math.pow(y - this.startPoint.y, 2)) / 2,
					// 圆心位置
					left = (x + this.startPoint.x) / 2, top = (y + this.startPoint.y) / 2;
					ctx.beginPath();
					for (var i = 0; i < 5; i++) {
						ctx.lineTo(Math.cos((54 + i * 72) / 180 * Math.PI) * radius * 0.4 + left, -Math.sin((54 + i * 72) / 180 * Math.PI) * radius * 0.4 + top);
						ctx.lineTo(Math.cos(((90 + i * 72) % 360) / 180 * Math.PI) * radius + left, -Math.sin(((90 + i * 72) % 360) / 180 * Math.PI) * radius + top);
					}
					ctx.closePath();
					ctx.stroke();
					return true;
				}
			},
			// 手绘
			FREEHAND: {
				key: 'FREEHAND',
				_draw: function(x, y) {
					var ctx = this.ctx;
					ctx.lineTo(x, y);
					ctx.stroke();
					return true;
				}
			},
			// 文本
			TEXT: {
				key: 'TEXT',
				_draw: function(x, y) {
					var input = document.createElement('textarea');
					input.className = 'canvas-text-input';
					var c = this, ctx = this.ctx, left = this.startPoint.x - 2 > 2 ? this.startPoint.x - 2 : 2, top = this.startPoint.y - 12 > 5 ? this.startPoint.y - 12 : 5;
					input.style.left = left + 'px';
					input.style.top = top + 'px';
					this.canvas.parentNode.appendChild(input);
					input.focus();
					var printText = function(text, left, top) {
						var s = '', width = c.width - left - 20;
						for (var index = 0, len = text.length; index < len; index++) {
							s += text[index];
							if (c.ctx.measureText(s).width > width) {
								c.ctx.fillText(s, left, top);
								top += 20;
								s = '';
							}
						}
						if (s) {
							c.ctx.fillText(s, left, top);
						}
					};
					input.onblur = function() {
						if (this.value) {
							c.ctx.font = "bold 16px Arial";
							printText(this.value, left + 5, top + 17);
						}
						c.canvas.parentNode.removeChild(input);
					};
					return true;
				}
			}
		},
		// 绘制图形
		drawShape: function(x, y) {
			var type = this.shapeType;
			if (this.shapeTypes[type] && this._checkPoint(x, y)) {
				return this.shapeTypes[type]._draw.call(this, x, y);
			}
			return false;
		},
		// 导出图片
		exportImage: function() {
			//		var url = this.canvas.toDataURL('image/png'), img = new Image();
			//		img.src = url;
			//		this.imgDiv.appendChild(img);
			var image = this.canvas.toDataURL("image/jpeg", 1);//.replace("image/png", "image/octet-stream;Content-Disposition: attachment;filename=" + new Date().getTime() + ".png");
			window.location.href = image;
		},
		// 事件绑定
		bindEvent: function() {
			var pc = this, imgData,
			// 绘画程序
			drawHandle = function(x, y) {
				if (pc.shapeType !== 'TEXT') {
					pc.ctx.putImageData(imgData, 0, 0);
				}
				pc.drawShape(x, y);
			}, lastHandle = function(x, y) {
				drawHandle(x, y);
				pc.startPoint = {};
			};
			// 鼠标按下
			_$.on(this.canvas, 'mousedown', function(e) {
				var p = _$.getEventPosition(this, e);
				pc.startPoint = {
					x: p.left,
					y: p.top
				};
				pc.ctx.beginPath();
				pc.ctx.moveTo(p.left, p.top);
				imgData = pc.ctx.getImageData(0, 0, pc.width, pc.height);
				pc.mousedown = true;
			});
			// 鼠标放开
			_$.on(this.canvas, 'mouseup mouseleave', function(e) {
				if (pc.mousedown && (pc.mousemove || pc.shapeType === 'TEXT')) {
					var p = _$.getEventPosition(this, e);
					_$.throttle(lastHandle, {
						args: [p.left, p.top],
						time: 150
					});
				}
				pc.mousedown = false;
				pc.mousemove = false;
			});

			// 鼠标移动
			_$.on(this.canvas, 'mousemove', function(e) {
				if (!pc.mousedown) {
					return;
				}
				var p = _$.getEventPosition(this, e);
				// 手绘需要实时触发
				if (pc.shapeType === 'FREEHAND') {
					pc.drawShape(p.left, p.top);
				} else if (pc.shapeType !== 'TEXT') {
					_$.amble(drawHandle, {
						args: [p.left, p.top],
						time: 100
					});
				}
				pc.mousemove = true;
			});
		}
	});
	return PaintCanvas;
});